﻿#region Imports
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Windows.Forms;
using System.Xml;
using System.Reflection;
using System.IO;
using BulkRenamer.Util;
using BulkRenamer.Util.Enums;
#endregion

namespace RequirementLogger.Utils
{
    public static class RLUtilities
    {
        #region Methods
        public static IEnumerable<T> ReadFromXML<T>(string basePath, string xmlName, string xmlExtn = ".xml") where T : new()
        {
            ObservableCollection<T> res = new ObservableCollection<T>();
            if (String.IsNullOrEmpty(xmlExtn)) xmlExtn = ".xml";
            string xmlPath = basePath.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(xmlName) + '.' + xmlExtn.Trim('.');

            if (!String.IsNullOrEmpty(basePath) && !String.IsNullOrEmpty(basePath)
                && Utilities.ValidatePath(xmlPath, Enumerators.ePathValidation.File))
            {
                // Read from XML :: http://support.microsoft.com/kb/307548
                XmlTextReader reader = new XmlTextReader(xmlPath);
                string sXML = ""; string sJson = "";
                PropertyInfo prop = null; T t = new T { }; string nodeName = "";
                List<string> ignore = new List<string>();
                string className = Path.GetExtension(typeof(T).ToString()).Trim('.'); // typeof( T).GetType().ToString()
                ignore.AddRange(new string[] { "ItemCollection", "ArrayOf" + className });
                while (reader.Read())
                {
                    nodeName = reader.Name;
                    switch (reader.NodeType)
                    {
                        case XmlNodeType.XmlDeclaration:
                            sXML += ("<?" + nodeName + " " + reader.Value + "?>" + Utilities.cNewLine);
                            break;

                        case XmlNodeType.Element: // The node is an element.
                            //nodeName = reader.Name;
                            if (!ignore.Contains(nodeName))
                            {
                                sXML += "<" + nodeName + ">" + (nodeName == className ? Utilities.cNewLine : "");
                                //Console.Write("<" + reader.Name);
                                //Console.WriteLine(">");

                                if (nodeName == className)
                                {
                                    t = new T { };
                                    //sJson += ("{\"" + nodeName + "\" : {");
                                    sJson += ("{"); ;
                                }
                                else
                                {
                                    prop = t.GetType().GetProperty(nodeName);
                                    sJson += ("\"" + nodeName + "\" : ");
                                }
                            }

                            break;

                        case XmlNodeType.Text: //Display the text in each element.
                            if (!ignore.Contains(nodeName))
                            {
                                sXML += reader.Value;
                                //Console.WriteLine (reader.Value);

                                object obj /*= Utilities.ConvertTo<>(reader.Value, prop.PropertyType);*/
                                    = Convert.ChangeType(reader.Value, prop.PropertyType);
                                if (nodeName != className)
                                {
                                    prop.SetValue(t, obj, null);
                                    sJson += ("\"" + reader.Value + "\", ");
                                }
                            }

                            break;

                        case XmlNodeType.EndElement: //Display the end of the element.
                            //nodeName = reader.Name;
                            if (!ignore.Contains(nodeName))
                            {
                                sXML += "</" + reader.Name + ">" + Utilities.cNewLine;
                                //Console.Write("</" + reader.Name);
                                //Console.WriteLine(">");

                                if (nodeName == className)
                                {
                                    //sJson = sJson.Trim().TrimEnd(',') + "}}, ";
                                    sJson = sJson.Trim().TrimEnd(',') + "}, ";
                                }
                                else
                                {
                                    res.Add(t);
                                    sJson += "";
                                }
                            }

                            break;

                        default:
                            sXML += reader.Value;
                            break;
                    }
                }

                sXML = File.ReadAllText(xmlPath, Utilities.DefaultEncoding);
                sJson = "[" + sJson.Trim().TrimEnd(',') + "]";
                res = Serializer.DeSerializeFromFormattedData<ObservableCollection<T>>(Enumerators.eSerializationType.JSon, sJson);
                res = Serializer.DeSerializeFromFormattedData<ObservableCollection<T>>(Enumerators.eSerializationType.Xml, sXML);
                MessageBox.Show(sXML, "XML");
                MessageBox.Show(sJson, "JSON");

                return res.AsEnumerable();
            }

            return null;
        }
        #endregion
    }
}
